package com.example.rbq.client

import android.util.Log
import com.example.lib_core.task.Task
import com.example.lib_core.util.JsonUtils
import com.example.lib_core.util.StringUtil
import com.example.lib_core.util.postUI
import java.io.IOException
import java.net.DatagramPacket

object EmulatorManage {

    const val DEFAULT_EMULATOR_PORT = 7700

    val client = Emulator(Emulator.Option())

    private var onResponseAction: ((rpc: DebugRPC) -> Unit)? = null

    fun connectSever() {
        Task.singleTask {
            client.open()
        }.success {
            receiverTask.start()
            println("open client")
        }.error {
            Log.e("EmulatorManage","连接模拟器失败")
            it.printStackTrace()
        }.start()
    }

    fun disconnectSever() {
        receiverTask.cancel()
        Task.singleTask {
            client.close()
        }.success {
            println("close client")
        }.error {
            it.printStackTrace()
        }.start()
    }

    fun callRPC(text: String) {
        Task.singleTask {
            if (client.isOpened) {
                client.sendTo(text.toByteArray())
            }
        }.success {
            println("call")
        }.error {
            it.printStackTrace()
        }.start()
    }

    fun setOnResponseAction(action: (rpc: DebugRPC) -> Unit): EmulatorManage {
        this.onResponseAction = action
        return this
    }

    private var receiverTask = Task.singleTask {
        val buffer = ByteArray(1024 * 16)
        val packet = DatagramPacket(buffer, buffer.size)
        while (true){
            try{
                val socket = client.udpSocket
                if (socket == null) {
                    Thread.sleep(500)
                    Log.e("EmulatorManage","socket is null")
                    continue
                }
                socket.receive(packet)

                val length = packet.length
                if (length <= 0) {
                    Thread.sleep(50)
                    Log.e("EmulatorManage","recv $length bytes")
                    continue
                }
                val recvBuffer =  ByteArray(length)
                val serviceAddress = packet.address
                val servicePort = packet.port
                Log.e("xiao","serviceAddress:$serviceAddress")
                Log.e("xiao","servicePort:$servicePort")
                System.arraycopy(buffer, 0, recvBuffer, 0, length)
                val str = StringUtil.byteToString(recvBuffer)
                val rpc = JsonUtils.gson.fromJson(str,DebugRPC::class.java)
                postUI {
                    onResponseAction?.invoke(rpc)
                }
            }catch (e: IOException){
                e.printStackTrace()
            }
        }
    }.error {
        Log.e("EmulatorManage",it.message ?: "")
        it.printStackTrace()
    }
}